import {redisSQLDatabase} from 'TYPE'
import {cache, createIndex} from '../cache'
import knex from '../sql'

declare module 'knex/types/tables' {
    interface Notification {
        id: number
        uid: number
        type: string
        p1: string
        p2: string
        p3: string
        time: Date
        has_read: Boolean
        deleted: Boolean
    }
    interface Tables {
        notifications: Notification
    }
}
import {Notification} from 'knex/types/tables'
import {SchemaFieldTypes} from 'redis'
import {userDB} from './user.db'
import {postDB} from './post.db'
class NotificationDB implements redisSQLDatabase {
    indexName = 'idx:notification'
    async initIndex(del=false) {
        if (del) {
            await cache.ft.dropIndex(this.indexName)
        }
        await createIndex(this.indexName, {
            '$.uid': {
                type: SchemaFieldTypes.TAG as any,
                AS: 'uid'
            },
            '$.time': {
                type: SchemaFieldTypes.NUMERIC as any,
                SORTABLE: true,
                AS: 'time'
            },
            '$.type':{
                type: SchemaFieldTypes.TAG as any,
                AS: 'type'
            }

        }, {
            ON: 'JSON', PREFIX: 'notification:',
        })
    }
    async getNotification(id: number) {
        const key = `notification:${id}`
        return await cache.json.get(key)
    }
    async getNotificationByUid(uid: number, paged: number, notifications_per_page: number) {
        let ns = await cache.ft.search(this.indexName, `@uid:{${uid}}`, {
            SORTBY: {BY: 'time' as any, DIRECTION: 'DESC'},
            LIMIT: {from: (paged - 1) * notifications_per_page, size: notifications_per_page},
        })
        let notifications = {total:0,list:[]}
        notifications.total = ns.total
        
        for(let notification of ns.documents){
            notifications.list.push(notification.value as any)
        }
        return notifications
    }
    async deleteNotifiaction(id: number) {
        const key = `notification:${id}`
        let notification = await this.getNotification(id)
        if (!notification) return null
        else {
            cache.json.del(key)
            try {
                knex('notifications').where({id}).update({deleted: true})
            } catch (error) {
                console.error(error);
            }
        }
    }
    async addNotification(uid: number, type: string, p1: string = null, p2: string = null, p3: string = null) {
        let flag = false
        let notification = {uid, type, p1, p2, p3, id: null}
        await knex('notifications').insert(notification).then(n => {
            if (n.length) {
                flag = true
                knex('notifications').select().where({id: n[0]}).first().then(n => {
                    const key = `notification:${n.id}`;
                    this.convertToRedisJSON(n)
                    cache.json.set(key, '$', n as any)
                })
            }
        })
        return flag
    }

    async markReadNotification(id: number) {
        let notification = await this.getNotification(id)
        if (!notification) return null
        else {
            (notification as any).has_read = true
            return notification
        }
    }
    convertToRedisJSON(notification: Notification) {
        notification.time = notification.time.valueOf() as any
        // (notification as any).content = this.translate(notification);
        (notification as any).uid += ''
    }
    // 通知的具体内容，交给前端实现
    // translate(notification: Notification): string {
    //     let res: string
    //     switch (notification.type) {
    //         case 'comment':
    //             // const commenter = await userDB.getUserById(Number(notification.p1))
    //             // const post = await postDB.getPostById(Number(notification.p2))
    //             res = `你的帖子${notification.p1}被${notification.p2}回复了。`
    //             break;

    //         default:
    //             res = notification.p1;
    //     }
    //     return res ?? ''
    // }
    async loadAll() {
        await cache.keys('notification:*').then(async (keys) => {
            for (const key of keys) {
                await cache.del(key)
            }
        })
        await knex('notifications').where('deleted', false).select().then(ns => {
            console.log(ns);
            
            for (const n of ns) {
                const key = `notification:${n.id}`;
                this.convertToRedisJSON(n)
                cache.json.set(key, '$', n as any)
            }
        })
    }
}
export const notificationDB = new NotificationDB()
